package batchprocessor;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PipeCommand {

    // Private variables
    List<Command> commands;
    String id;

    // Command Class constructor
    public PipeCommand(List<Command> n_commands) {
        commands = n_commands;
    }

    // Default Constructor
    public PipeCommand() {
        commands = new ArrayList();
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Command getHead() {
        return commands.get(0);
    }

    public Command getTail() {
        return commands.get(commands.size() - 1);
    }
    
    public void addCommand(Command command) {
        commands.add(command);
    }
    // Start the process for this command
    public void start(String dir) throws ProcessException {
        System.out.println("Starting pipe command " + id);
        
        // Start and link each process
        for (int i = 0; i < commands.size(); i++) {

            // Create process builder for the the processes
            ProcessBuilder builder = new ProcessBuilder();

            // Set working directory
            builder.directory(new File(dir));
            
            List<String> command0 = new ArrayList<>();
            command0.add(commands.get(i).getPath());

            if (!"Null".equals(this.getHead().getCommands())) {
                String[] command_strings = commands.get(i).getCommands().split("\\s+");
                command0.addAll(Arrays.asList(command_strings));
            }
            
            // Set the input and output files
            if (commands.get(i).equals(getHead())) {
                builder.redirectInput(new File(dir, commands.get(i).getInFile()));
            } else if (commands.get(i).equals(getTail())) {
                builder.redirectOutput(new File(dir, commands.get(i).getOutFile()));
            }
                
            builder.command(command0);

            // Start the command process
            try {
                // Start the first process
                commands.get(i).process = builder.start();

            } catch (IOException ex) {
                Logger.getLogger(PipeCommand.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

         // Pipe the commands
        for (int i = 0; i < (commands.size() - 1); i++)
        {
            try (OutputStream os = commands.get(i+1).process.getOutputStream()) {
                InputStream fis = commands.get(i).process.getInputStream();

                int achar;
                while ((achar = fis.read()) != -1) {
                    os.write(achar);
                }
                os.close();
            } catch (IOException ex) {
                Logger.getLogger(PipeCommand.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    // Wait for this process to complete
    public void finish() throws ProcessException {
        for (Command command : commands) {
            command.finish();
        }
        
        System.out.println("Pipe command "+id+" finished");
    }
}
